package com.rmd.mrcp.protocol;

import com.rmd.mrcp.protocol.mrcp.mrcp4j.MrcpMethodName;
import com.rmd.mrcp.protocol.mrcp.mrcp4j.message.MrcpEvent;
import com.rmd.mrcp.protocol.peers.media.AbstractSoundManager;
import com.rmd.mrcp.protocol.peers.sip.core.useragent.SipListener;
import com.rmd.mrcp.protocol.peers.sip.core.useragent.UserAgent;
import com.rmd.mrcp.protocol.peers.sip.syntaxencoding.SipUriSyntaxException;
import com.rmd.mrcp.protocol.peers.sip.transport.SipRequest;
import com.rmd.mrcp.protocol.peers.sip.transport.SipResponse;
import com.rmd.mrcp.protocol.socketclient.SpeakConfig;
import com.rmd.mrcp.protocol.utils.XmlParse;
import lombok.extern.slf4j.Slf4j;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.net.SocketException;
import java.util.UUID;
import java.util.concurrent.ArrayBlockingQueue;

@Slf4j
public class MrcpSynthJavaClient implements SipListener {

    public  static  final String text = "关于高炉炼铁行业垂直大模型构建路线的探讨与简易测试";

//    public static final String audioPathRight  = "/Users/yinxingpan/Downloads/user-b8xSiBGOEE-PCMU.pcm";
    public static final String LocalHostIp ="172.17.0.1";  // 本地局域网ip
    public static final String MrcpServerIp ="172.17.0.2";   // mrcp-server 外网ip
    //public static final String LocalHostIp ="127.0.0.1";  // 本地局域网ip
    //public static final String MrcpServerIp ="127.0.0.1";   // mrcp-server 外网ip
    public static final String MrcpServerPort ="7010";  // mrcp-server port
    public static  boolean testRun = true;

    public static final int MRCP_STATUS_INIT = 0;
    public static final int MRCP_STATUS_RUNING = 1;
    public static final int MRCP_STATUS_STOPPED = 2;
    public static final String MSG_QUIT = "STOP";

    private UserAgent userAgent;
    private SipRequest sipRequest;
    private volatile int mrcp_status = MRCP_STATUS_INIT;

    public MrcpSynthJavaClient() throws SocketException, FileNotFoundException {
        this.userAgent = new UserAgent(this,
                new SpeakConfig(LocalHostIp, new ArrayBlockingQueue(100)),
                null, new AbstractSoundManager() {
            FileOutputStream fos = null;
            @Override
            public void init() {
                try {
                    fos = new FileOutputStream(UUID.randomUUID().toString()+".wav", true);
                }catch (Exception e){
                    e.printStackTrace();
                }

            }

            @Override
            public void close(){
                if (fos != null) {
                    try {

                        fos.close();
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public int writeData(byte[] buffer, int offset, int length) {
                //System.out.println("length:"+length);
                if (fos != null){
                    try {

                        fos.write(buffer);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
                return length;
            }

            @Override
            public byte[] readData() {
                return new byte[0];
            }
        }, MrcpMethodName.SPEAK);
        /*
        this.userAgent.setGarmmar(
                "<grammar xmlns=\"http://www.w3.org/2001/06/grammar\" xml:lang=\"en-US\" version=\"1.0\" mode=\"voice\" root=\"digit\">\n" +
                "  <rule hotword_id=\"test_hotword\" customization_id=\"test_customization_id\"/>\n" +
                "</grammar>");

         */
        this.userAgent.setSpeakContent(text);
        log.debug("MrcpSynthJavaClient 初始化完");
    }

    public UserAgent getUserAgent(){
        return this.userAgent;
    }

    public boolean isRecording(){
        return mrcp_status == MRCP_STATUS_RUNING;
    }
    public void stop(){
        mrcp_status = MRCP_STATUS_STOPPED;
    }
    public void start() throws SocketException {
        mrcp_status = MRCP_STATUS_RUNING;
        log.debug("MrcpSynthJavaClient 开始启动!");
        /* 读取数据流，发送 */
        new Thread(){
            public void run() {
                try {
                    sipRequest = userAgent.invite("sip:mrcp@"+MrcpServerIp+":"+MrcpServerPort, null);
                } catch (SipUriSyntaxException e) {
                    e.printStackTrace();
                }


                //FileInputStream fileInputStream = new FileInputStream(audioPathLeft);
                byte buffer[] = null;
                try {
                    while (userAgent.getMrcpStatus()!=1){
                        Thread.sleep(30);
                    }
                    while (isRecording()) {
                        // status 为1 时候 mrcp 建立成功，可以写入数据了
                        /*
                        if(userAgent.getMrcpStatus()==1 && buffer!=null){
                            userAgent.getConfig().getOutstream().write(buffer);
                        }

                         */
                        Thread.sleep(1000);
                    }
                    // 主动断开 hangup()
                    userAgent.hangup(sipRequest);
                } catch (Exception e) {
                    log.error("error", e);
                }

            }
        }.start();

    }

    public static String printAsrResult(Object obj) {
        String res;
        if(obj instanceof MrcpEvent){
            MrcpEvent event  = (MrcpEvent) obj;
            if(event !=null && event.hasContent()){
                String content = event.getContent().replace("\u0000", "");
                res = XmlParse.readAsrData(content);
            }else{
                res = "null";
            }
        }else if(obj instanceof String){
            res = (String) obj;
        }else{
            res = obj.toString();
        }
        return res;
    }



    @Override
    public void registering(SipRequest sipRequest) { }

    @Override
    public void registerSuccessful(SipResponse sipResponse) {

    }
    @Override
    public void registerFailed(SipResponse sipResponse) { }

    @Override
    public void incomingCall(SipRequest sipRequest, SipResponse provResponse) { }

    @Override
    public void remoteHangup(SipRequest sipRequest) { }

    @Override
    public void ringing(SipResponse sipResponse) { }

    @Override
    public void calleePickup(SipResponse sipResponse) { }

    @Override
    public void error(SipResponse sipResponse) { }


    public static void main(String[] args) {

        try {


            MrcpSynthJavaClient javaMrcpUtil = new MrcpSynthJavaClient();

            //javaMrcpUtil_Left.start();
            javaMrcpUtil.start();

            /* 声道接收语音 */
            new Thread(){
                public void run() {
                    while(javaMrcpUtil.isRecording()){
                        try {
                            Object obj  = javaMrcpUtil.getUserAgent().getConfig().getReceivedQueue().take();
                            if(MSG_QUIT.equals(obj)){
                                log.debug("tts:" + printAsrResult(obj));
                                break;
                            }
                            log.debug("tts:" + printAsrResult(obj));
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }

                }
            }.start();

            Thread.sleep(30000);
            log.debug("时间到了,现在停止合成");

            javaMrcpUtil.stop();
        } catch (SocketException | InterruptedException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}
